package com.smart.service.impl;

import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.smart.common.enums.BooleanEnum;
import com.smart.common.utils.AssertUtil;
import com.smart.context.SessionContext;
import com.smart.mapper.*;
import com.smart.model.customdo.ProjectADO;
import com.smart.model.convert.ManageUserRegistrationConvert;
import com.smart.model.domain.*;
import com.smart.model.dtomapper.HotWorkDtoMapper;
import com.smart.model.dtomapper.ProjectUseControlDtoMapper;
import com.smart.model.request.HotWorkRequest;
import com.smart.model.request.ProjectUseControlRequest;
import com.smart.model.vo.*;
import com.smart.service.DictItemService;
import com.smart.service.HotWorkService;
import com.smart.model.convert.HotWorkConvert;
import com.smart.service.ProjectUseControlService;
import com.smart.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.smart.utils.PageUtils.getOrderBy;

/**
 * @author zhanghong
 */
@Slf4j
@Service
public class HotWorkServiceImpl extends ServiceImpl<HotWorkMapper, HotWorkDO> implements HotWorkService {
    @Autowired
    private HotWorkMapper hotWorkMapper;
    @Autowired
    private ManageUserRegistrationMapper userRegistrationMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private UnitMapper unitMapper;
    @Autowired
    private DictItemService dictItemService;
    @Autowired
    private StreetMapper streetMapper;
    @Autowired
    private ProjectUseControlService useControlService;
    @Autowired
    private ProjectUseControlMapper projectUseControlMapper;
    @Autowired
    private JiansheProjectMapper jiansheProjectMapper;
    @Autowired
    private ProjectStatusAxisMapper axisMapper;


    @Override
    public HotWorkVO getDetailByKey(long id) {
        HotWorkDO hotWorkDO = hotWorkMapper.selectDODetailById(id);
        if(ObjectUtils.isEmpty(hotWorkDO)){
            return null;
        }
        List<HotWorkVO> list = new ArrayList<>();
        HotWorkVO hotWorkVO = HotWorkDtoMapper.INSTANCE.do2VO(hotWorkDO);
        list.add(hotWorkVO);
        fillInfo(list);
        ProjectDO projectDO = projectMapper.selectDOById(hotWorkDO.getProjectId());
        if (!ObjectUtils.isEmpty(projectDO)){
            if (!ObjectUtils.isEmpty(projectDO.getEngineeringType())){
                List<DictItemVO> dictItemVOS = dictItemService.queryDictItemByDictCode("PROJECT_TYPE");
                DictItemVO dictItemVO1 = dictItemVOS.stream().filter(dictItemVO -> dictItemVO.getDictItemCode().equals(projectDO.getEngineeringType())).findFirst().orElse(null);
                if (!ObjectUtils.isEmpty(dictItemVO1)) {
                    hotWorkVO.setEngineeringType(dictItemVO1.getDictItemName());
                }
            }
            hotWorkVO.setAddress(streetMapper.selectDOByCode(projectDO.getStreetCode()).getName());
            hotWorkVO.setQualityRegistrationNumber(projectDO.getQualityRegistrationNumber());
            hotWorkVO.setShigongUnit(projectDO.getShigongUnit());
        }
        return hotWorkVO;
    }

    /**
     * 动火作业清单查询
     * @param request
     * @param pageable
     * @return
     */
    @Override
    public PageInfo<HotWorkVO> pageDetailedList(HotWorkRequest request, Pageable pageable) {
        Long jiansheUnitId = SessionContext.getJiansheUnitId();
        if (!ObjectUtils.isEmpty(jiansheUnitId)) {
            List<Long> projectIds = jiansheProjectMapper.selectAllProjectId(jiansheUnitId);
            request.setProjectIds(projectIds);
        }
        Long projectId = SessionContext.getProjectId();
        if (!ObjectUtils.isEmpty(projectId)){
            request.setProjectId(projectId);
        }
        Map<String,Date> time = hotWorkMapper.selectTimeScop(request);
        PageHelper.startPage(request.getPageNum(),request.getPageSize(),getOrderBy(pageable.getSort())).setReasonable(true);
        List<HotWorkDO> list = hotWorkMapper.pageDetailedList(request);
        PageInfo pageInfo = new PageInfo(list);
        PageHelper.clearPage();
        List<HotWorkVO> hotWorkVOList = HotWorkConvert.buildHotWorkVoList(list);
        fillInfo(hotWorkVOList);
        if (!ObjectUtils.isEmpty(hotWorkVOList)) {
            HotWorkVO hotWorkVO = hotWorkVOList.get(0);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd");
            Date hotWorkDateStart = request.getHotWorkDateStart();
            Date hotWorkDateEnd = request.getHotWorkDateEnd();
            if (!ObjectUtils.isEmpty(hotWorkDateStart)&&!ObjectUtils.isEmpty(hotWorkDateEnd)){
                hotWorkVO.setTimeScope(dateFormat.format(hotWorkDateStart)+"~"+dateFormat.format(hotWorkDateEnd));
            }else {
                if (!ObjectUtils.isEmpty(time)) {
                    hotWorkVO.setTimeScope(dateFormat.format(time.get("minTime")) + "~" + dateFormat.format(time.get("maxTime")));
                }
            }
        }
        pageInfo.setList(hotWorkVOList);
        return pageInfo;
    }

    private void fillInfo(List<HotWorkVO> hotWorkList) {
        for (HotWorkVO vo : hotWorkList) {
            //项目信息
            ProjectDO project = projectMapper.selectDOById(vo.getProjectId());
            if (project != null) {
                vo.setProjectName(project.getProjectName());
                vo.setProjectNumber(project.getProjectNumber());
                vo.setQualityRegistrationNumber(project.getQualityRegistrationNumber());
            }
            //分包单位信息
            UnitDO unitDO = unitMapper.selectDOById(vo.getUnitId());
            if (!ObjectUtils.isEmpty(unitDO)){
                vo.setUnitName(unitDO.getUnitName());
                vo.setUnitDetailName(unitDO.getUnitDetailName());
            }
            //动火人信息
            ManageUserRegistrationDO registrationDO = userRegistrationMapper.selectById(vo.getHotWorkPerson());
            if (!ObjectUtils.isEmpty(registrationDO)){
                vo.setHotWorkPersonName(registrationDO.getUserName());
                vo.setHotWorkPersonPhoto(registrationDO.getEntranceFacePhoto());
                vo.setHotWorkPersonIdcard(registrationDO.getIdCard());
                vo.setHotWorkPersonIdcardPhoto(registrationDO.getIdPhoto());
            }
            //看火人1
            ManageUserRegistrationDO registrationDOOne = userRegistrationMapper.selectById(vo.getHotWorkLookPersonOne());
            if (!ObjectUtils.isEmpty(registrationDOOne)){
                vo.setHotWorkLookPersonOneName(registrationDOOne.getUserName());
                vo.setHotWorkLookPersonOnePhoto(registrationDOOne.getEntranceFacePhoto());
                vo.setHotWorkLookPersonOneIdcard(registrationDOOne.getIdCard());
                vo.setHotWorkLookPersonOneIdcardPhoto(registrationDOOne.getIdPhoto());
            }
            //看火人2
            Long hotWorkLookPersonTwo = vo.getHotWorkLookPersonTwo();
            if (!ObjectUtils.isEmpty(hotWorkLookPersonTwo)){
                ManageUserRegistrationDO registrationDOTwo = userRegistrationMapper.selectById(vo.getHotWorkLookPersonTwo());
                if (!ObjectUtils.isEmpty(registrationDOTwo)){
                    vo.setHotWorkLookPersonTwoName(registrationDOTwo.getUserName());
                    vo.setHotWorkLookPersonTwoPhoto(registrationDOTwo.getEntranceFacePhoto());
                    vo.setHotWorkLookPersonTwoIdcard(registrationDOTwo.getIdCard());
                    vo.setHotWorkLookPersonTwoIdcardPhoto(registrationDOTwo.getIdPhoto());
                }
            }

        }
    }

    /**
     *监管端-动火作业管理列表分页查询
     * @param request
     * @return
     */
    @Override
    public com.smart.common.PageInfo listQuerySupervise(HotWorkRequest request) {
        List<Long> projectIds = axisMapper.selectDOByRequest(request);
        List<ProjectADO> hotWorkA = new ArrayList<>();
        if (!ObjectUtils.isEmpty(projectIds)){
            request.setProjectIds(projectIds);
            hotWorkA = hotWorkMapper.selectDOListByIds(request);
            if (ObjectUtils.isEmpty(hotWorkA)){
                request.setProjectIds(null);
            }
        }
        List<ProjectADO> hotWorkC = hotWorkMapper.selectDOListByReq(request);
        hotWorkA.addAll(hotWorkC);
        Boolean exclude = request.getExclude();
        if (ObjectUtils.isEmpty(exclude)){
            exclude = false;
        }
        if (exclude){
            List<ProjectADO> projectADOS = hotWorkA.stream().filter(item -> item.getHotWorkCount() > 0).collect(Collectors.toList());
            List<ProjectADO> collect = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(projectADOS)) {
                collect = projectADOS.stream().sorted(Comparator.comparing(ProjectADO::getCreateTime).reversed()).collect(Collectors.toList());
            }
            List<ProjectADO> page = ListUtil.page(request.getPageNum() - 1, request.getPageSize(), collect);
            return new com.smart.common.PageInfo(request.getPageNum(), request.getPageSize(), page, collect.size());
        }else {
            List<ProjectADO> collect = hotWorkA.stream().sorted(Comparator.comparing(ProjectADO::getCreateTime).reversed()).collect(Collectors.toList());
            List<ProjectADO> page = ListUtil.page(request.getPageNum() - 1, request.getPageSize(), collect);
            return new com.smart.common.PageInfo(request.getPageNum(), request.getPageSize(), page, collect.size());
        }
    }

    /**
     * 云管理-动火作业管理列表分页查询
     * @param request
     * @param pageable
     * @return
     */
    @Override
    public PageInfo<List<ProjectADO>> listQueryManage(HotWorkRequest request, Pageable pageable) {
        PageHelper.startPage(request.getPageNum(),request.getPageSize(),getOrderBy(pageable.getSort())).setReasonable(true);
        Long jiansheUnitId = SessionContext.getJiansheUnitId();
        request.setJiansheUnitId(jiansheUnitId);
        List<ProjectADO> hotWorkADOS = hotWorkMapper.listQueryManage(request);
        return new PageInfo(hotWorkADOS);
    }

    @Override
    public ListQuerySuperviseCount listQuerySuperviseCount(HotWorkRequest request) {
        ListQuerySuperviseCount count = new ListQuerySuperviseCount();
        List<Long> projectIds = axisMapper.selectDOByRequest(request);
        List<ProjectADO> hotWorkA = new ArrayList<>();
        if (!ObjectUtils.isEmpty(projectIds)){
            request.setProjectIds(projectIds);
            hotWorkA = hotWorkMapper.selectDOListByIds(request);
            if (ObjectUtils.isEmpty(hotWorkA)){
                request.setProjectIds(null);
            }
        }
        List<ProjectADO> hotWorkC = hotWorkMapper.selectDOListByReq(request);
        hotWorkA.addAll(hotWorkC);
        Boolean exclude = request.getExclude();
        if (ObjectUtils.isEmpty(exclude)){
            exclude = false;
        }
        if (exclude){
            List<ProjectADO> projectADOS = hotWorkA.stream().filter(item -> item.getHotWorkCount() > 0).collect(Collectors.toList());
            count.setUpload(projectADOS.size());
            count.setNotUpload(0);
            return count;
        }else {
            List<ProjectADO> projectADOS = hotWorkA.stream().filter(item -> item.getHotWorkCount() > 0).collect(Collectors.toList());
            count.setUpload(projectADOS.size());
            count.setNotUpload(hotWorkA.size()-projectADOS.size());
            return count;
        }
    }

    /**
     * 云服务端-动火作业新增
     * @param request
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public  Map<String, Object> add(HotWorkRequest request) {
        //动火作业开通校验
        Long projectId = SessionContext.getProjectId();
        request.setProjectId(projectId);
        useControlService.hotWorkOpenValid(projectId);
        Date hotWorkDateStart = request.getHotWorkDateStart();
        AssertUtil.assertNotNull(hotWorkDateStart,"作业时间不能为空");
        String hotWorkPosition = request.getHotWorkPosition();
        String safetyMeasure = request.getSafetyMeasure();
        Long hotWorkLookPersonOne = request.getHotWorkLookPersonOne();
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(hotWorkLookPersonOne), "看火人1为必填");
        if (!ObjectUtils.isEmpty(hotWorkPosition)) {
            AssertUtil.assertTrue(hotWorkPosition.length() <= 100, "动火部位最多100字");
        }
        if (!ObjectUtils.isEmpty(safetyMeasure)) {
            AssertUtil.assertTrue(safetyMeasure.length() <= 200, "器材及安全措施最多200字");
        }
        AtomicInteger retryTimes = new AtomicInteger(1);
        return retryInsert(request, retryTimes);
    }

    @NotNull
    private Map<String, Object> retryInsert(HotWorkRequest request, AtomicInteger retryTimes) {
        String hotWorkCode = getMaxCode(retryTimes.get());
        HotWorkDO hotWorkDO = HotWorkDtoMapper.INSTANCE.request2DO(request);
        hotWorkDO.setCreateUser(request.getProjectId());
        hotWorkDO.setCreateTime(DateUtils.getNowDate());
        hotWorkDO.setDeleted(BooleanEnum.FALSE.getCode());
        hotWorkDO.setProjectId(request.getProjectId());
        Map<String, Object> map = new HashMap<>();
        try{
            hotWorkDO.setHotWorkCode(hotWorkCode);
            hotWorkMapper.insertDO(hotWorkDO);
            ProjectUseControlVO byProjectId = useControlService.getByProjectId(request.getProjectId());
            ProjectUseControlRequest controlRequest = new ProjectUseControlRequest();
            controlRequest.setProjectId(request.getProjectId());
            controlRequest.setId(byProjectId.getId());
            controlRequest.setHotWorkAvailableNum(byProjectId.getHotWorkAvailableNum()-1);
            controlRequest.setUpdateUser(SessionContext.getProjectId());
            ProjectUseControlDO projectUseControlDO = ProjectUseControlDtoMapper.INSTANCE.request2DO(controlRequest);
            projectUseControlMapper.updateDO(projectUseControlDO);
            map.put("success",true);
            map.put("message",null);
            return map;
        }catch (DuplicateKeyException e){
            e.printStackTrace();
            AtomicInteger atomicInteger = new AtomicInteger(retryTimes.addAndGet(1));
            log.info("作业编码重复,开始重新生成操作,当前重试第{}次",atomicInteger.get()-1);
            AssertUtil.assertTrue(atomicInteger.get()<3,"作业编码重复");
            retryInsert(request,atomicInteger);
            map.put("success",true);
            map.put("message","未知错误");
            return map;
        }
    }

    /**
     * 生成全平台唯一的作业编码
     * @return
     */
    @NotNull
    private String getMaxCode(Integer a) {
        Integer maxCode = hotWorkMapper.selectMaxHotWorkCode();
        Date nowDate = DateUtils.getNowDate();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateString = simpleDateFormat.format(nowDate);
        String hotWorkCode;
        if (ObjectUtils.isEmpty(maxCode)) {
            hotWorkCode = "DH" + dateString + 1;
        }else {
            Integer b = maxCode+a;
            hotWorkCode = "DH" + dateString +b;
        }
        return hotWorkCode;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByKey(HotWorkRequest request) {
        String hotWorkPosition = request.getHotWorkPosition();
        String safetyMeasure = request.getSafetyMeasure();
        Long hotWorkLookPersonOne = request.getHotWorkLookPersonOne();
        AssertUtil.assertTrue(!ObjectUtils.isEmpty(hotWorkLookPersonOne),"看火人1为必填");
        if (!ObjectUtils.isEmpty(hotWorkPosition)){
            AssertUtil.assertTrue(hotWorkPosition.length()<=100,"动火部位最多100字");
        }
        if (!ObjectUtils.isEmpty(safetyMeasure)){
            AssertUtil.assertTrue(safetyMeasure.length()<=200,"器材及安全措施最多200字");
        }
        HotWorkDO hotWorkDO = HotWorkDtoMapper.INSTANCE.request2DO(request);
        hotWorkDO.setUpdateUser(SessionContext.getProjectId());
        hotWorkDO.setUpdateTime(DateUtils.getNowDate());
        hotWorkMapper.updateDO(hotWorkDO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteByKey(long id) {
        hotWorkMapper.deleteDOById(id);
        return true;
    }

    /**
     * 动火人、看火人输入后校验
     * @param userName
     * @return
     */
    @Override
    public Object verify(String userName) {
        //根据名称查询在场人员
        Long projectId = SessionContext.getProjectId();
        List<ManageUserRegistrationDO> userRegistrationDOList = userRegistrationMapper.selectByName(userName,projectId);
        if (ObjectUtils.isEmpty(userRegistrationDOList)){
            return null;
        }
        List<ManageUserRegistrationVO> manageUserRegistrationVOS = ManageUserRegistrationConvert.buildManageUserRegistrationVoList(userRegistrationDOList);
        return manageUserRegistrationVOS;
    }

}
